package sim.core.mvc;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sim.core.annotation.Uri;
import sim.core.consts.PropertiesConst;
import sim.core.handler.ConfigHandler;
import sim.core.handler.ControllerHandler;
import sim.core.handler.RequestMethodHandler;
import sim.core.handler.UrlHandler;
import sim.core.utils.ClassPathUtils;
import sim.core.utils.PropUtils;
import sim.core.utils.ServletContextUtils;
import sim.core.utils.StringUtils;

/**
 * SimFilter
 */
@WebFilter("/*")
public class SimFilter implements Filter {
	private UrlHandler mappings = null;

	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		req.setCharacterEncoding("UTF-8");
		String uri = req.getRequestURI();
		String method = req.getMethod();
		boolean ignore = ServletContextUtils.DEFAULT_IGNORE.contains(uri.substring(uri.lastIndexOf(".") + 1));
		if (StringUtils.isNotBlank(uri) && uri.endsWith(ServletContextUtils.URI_SUFFIX) && !ignore) {
			uri = StringUtils.removeStart(uri, ServletContextUtils.CONTEXTPATH);
			ControllerHandler controller = mappings.getController(uri);
			if (null == controller) {
				resp.sendError(HttpServletResponse.SC_NOT_FOUND, "请求地址不存在");
				return;
			}
			List<String> requestMethods = RequestMethodHandler.getRequestMethod(controller.getRequestMethod());
			if (requestMethods.size() == 0 || (requestMethods.size() > 0 && requestMethods.contains(method))) {
				ServletContextUtils.setReqAndRes(req, resp);
				controller.invoke();
				ServletContextUtils.removeReqAndRes();
				return;
			} else {
				resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, String.format("请求地址不支持“%s”方式", method));
				return;
			}
		} else {
			chain.doFilter(request, response);
		}
	}

	/**
	 * 初始化信息
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// 获取web项目路劲
		ServletContextUtils.CONTEXTPATH = fConfig.getServletContext().getContextPath();

		// 读取配置文件
		PropUtils.load("application");

		String prop_request_suffix = PropUtils.getProp(PropertiesConst.PROP_REQUEST_SUFFIX);
		String prop_jsp = PropUtils.getProp(PropertiesConst.PROP_JSP);
		String prop_freemarker = PropUtils.getProp(PropertiesConst.PROP_FREEMARKER);
		// 修改请求地址后缀
		if (StringUtils.isNotBlank(prop_request_suffix)) {
			ServletContextUtils.URI_SUFFIX = prop_request_suffix;
		}
		// jsp资源存放位置
		if (StringUtils.isNotBlank(prop_jsp)) {
			ServletContextUtils.JSP_RESOURCES = prop_jsp;
		}
		// freemarker资源存放位置
		if (StringUtils.isNotBlank(prop_freemarker)) {
			ServletContextUtils.FREEMARKER_RESOURCES = prop_freemarker;
		}

		// 扫描项目下所有class文件
		List<Class<?>> clazzs = Scanner.getAllClass(ClassPathUtils.getRootClassPath(), null);

		// 执行有实现Config接口的类
		ConfigHandler configHandler = new ConfigHandler();
		configHandler.getConfigClass(clazzs).startConfig();

		// 保存UrlMapping
		System.out.println("UrlMapping Scan Start...");
		mappings = UrlHandler.setUrlMapping(clazzs, Uri.class);
		System.out.println("UrlMapping Scan is completed");
		System.out.println("ヽ(￣▽￣)ﾉ启动成功ヽ(￣▽￣)ﾉ");
	}

}
